package org.pangu.client.service.impl;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.pangu.api.ProductService;
import org.pangu.client.service.DeptService;
import org.pangu.common.Result;
import org.pangu.dto.ProductDTO;
import org.pangu.vo.ProductVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.annotation.Method;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.utils.ReferenceConfigCache;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.service.GenericService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class DeptServiceImpl implements DeptService {

//	@Reference(retries = 0, timeout = 900000000/* , group = "zzz" */)
//	@Reference(retries = 0, timeout = 900000000, methods = {@Method(name="findProduct",async = true)})
//	@Reference(retries = 0, timeout = 900000000, async = true)
//	@Reference(retries = 0, timeout = 900000000)
//	@Reference(retries = 0, timeout = 900000000, methods= {@Method(name="findProduct",onreturn="mynotify.onreturn")})
	@Reference(/*retries = 0,*/ timeout = 900000000)
	private ProductService productService;
	
	private final static Map<String, GenericService> cache = new ConcurrentHashMap<>();

	@Autowired
	private DefaultMQProducer defaultMQProducer;
	
	@Override
	public Result<ProductVO> getProduct(ProductDTO dto) {
//		RpcContext.getContext().setAttachment("dubbo.tag", "dev");
//		RpcContext.getContext().setAttachment(Constants.ASYNC_KEY, "true");
		
		Result<ProductVO> result = productService.findProduct(dto);
		log.info("okokokokokokokokokokokokokokokokokokokokok");
//		result = productService.findProduct(dto);
//		Future<Object> future = RpcContext.getContext().getFuture();
//		try {
//			result = (Result<ProductVO>) future.get();
//		} catch (InterruptedException | ExecutionException e) {
//			e.printStackTrace();
//		}
		//mq
//		Message msg = new Message("topic-zzz", JSONObject.toJSONString(dto).getBytes(StandardCharsets.UTF_8));
//		try {
//			SendResult send = defaultMQProducer.send(msg);
//			System.out.println(send);
//		} catch (MQClientException e) {
//			e.printStackTrace();
//		} catch (RemotingException e) {
//			e.printStackTrace();
//		} catch (MQBrokerException e) {
//			e.printStackTrace();
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		return result;
	}

	@Override
	public Result<ProductVO> getProductGeneric(ProductDTO dto) {
		GenericService svc = null;
		synchronized (cache) {
			svc = cache.get("org.pangu.api.ProductService");
			if (svc==null) {
				ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
				ApplicationConfig application = new ApplicationConfig();
				application.setName("pangu-client-consumer-generic");
				// 连接注册中心配置
				RegistryConfig registry = new RegistryConfig();
				registry.setAddress("zookeeper://114.67.85.120:2181");
				
				// 服务消费者缺省值配置
				ConsumerConfig consumer = new ConsumerConfig();
				consumer.setTimeout((int) 60000);
				consumer.setRetries(0);
				
				reference.setApplication(application);
				reference.setRegistry(registry);
				reference.setConsumer(consumer);
				reference.setInterface(org.pangu.api.ProductService.class);
				reference.setInterface(org.pangu.api.ProductService.class); // 弱类型接口名
//        reference.setVersion("");
//        reference.setGroup("");
				reference.setGeneric(true); // 声明为泛化接口
				//
				svc = reference.get();
				cache.put("org.pangu.api.ProductService", svc);
			}
		}
        Object target = svc.$invoke("findProduct", new String[]{ProductDTO.class.getName()}, new Object[]{dto});
        
        System.out.println(target);
        
		return null;
	}

	@Override
	public Result<Map> getProductGenericCache(ProductDTO dto) {
		ReferenceConfigCache referenceCache = ReferenceConfigCache.getCache();
		
		ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();//缓存，否则每次请求都会创建一个ReferenceConfig，并在zk注册节点，最终可能导致zk节点过多影响性能
		ApplicationConfig application = new ApplicationConfig();
		application.setName("pangu-client-consumer-generic");
		// 连接注册中心配置
		RegistryConfig registry = new RegistryConfig();
		registry.setAddress("zookeeper://114.67.85.120:2181");
		
		// 服务消费者缺省值配置
		ConsumerConfig consumer = new ConsumerConfig();
		consumer.setTimeout(1000000000);
		consumer.setRetries(0);
		
		reference.setApplication(application);
		reference.setRegistry(registry);
		reference.setConsumer(consumer);
		reference.setCheck(true);
		reference.setInterface(org.pangu.api.ProductService.class); // 弱类型接口名
//        reference.setVersion("");
//        reference.setGroup("");
		reference.setGeneric(true); // 声明为泛化接口
		GenericService svc = referenceCache.get(reference);//cache.get方法中会缓存 Reference对象，并且调用ReferenceConfig.get方法启动ReferenceConfig
//		RpcContext.getContext().setAttachment("my.custom", "dev");
        Object target = svc.$invoke("findProduct", new String[]{ProductDTO.class.getName()}, new Object[]{dto});//实际网关中，方法名、参数类型、参数是作为参数传入
        
		return Result.success((Map)target);
	
	}

}
